# Remix Author:JianRobSim
# reference: https://blog.csdn.net/python1639er/article/details/104048648
#            https://www.cnblogs.com/hch123/p/hch-hannuota.html
#   https://www.bilibili.com/video/av83689708?spm_id_from=333.788.b_636f6d6d656e74.4
import turtle
class Stack:
    def __init__(self):
        self.items = []
    def isEmpty(self):
        return len(self.items) == 0
    def push(self, item):
        self.items.append(item)
    def pop(self):
        return self.items.pop()
    def peek(self):
        if not self.isEmpty():
            return self.items[len(self.items) - 1]
    def size(self):
        return len(self.items)
 
def drawpole_3():  # 画出汉诺塔的poles
    t = turtle.Turtle()
    t.hideturtle()
    def drawpole_1(k):
        t.up()
        t.pensize(15)  # 柱子R
        t.speed(100)
        t.goto(300 * (k - 1), 100)  # 位置坐标
        t.down()
        t.goto(300 * (k - 1), -100)
        t.goto(300 * (k - 1) - 20, -100)
        t.goto(300 * (k - 1) + 20, -100)
    drawpole_1(0)  # 画出汉诺塔的poles[0]
    drawpole_1(1)  # 画出汉诺塔的poles[1]
    drawpole_1(2)  # 画出汉诺塔的poles[2]
# 定义颜色
FillColors = ["#d25b6a", "#d2835b", "#e5e234", "#83d05d", "#2862d2", "#35b1c0", "#5835c0"]
def creat_plates(n):  # 制造n个盘子
    plates = [turtle.Turtle() for i in range(n)]
    for i in range(n):
        plates[i].up()
        plates[i].hideturtle()
        plates[i].shape("square")#shape有arrow，turtle,circle,triangle,classic
        plates[i].shapesize(1, 8 - i)
        plates[i].goto(-300, -90 + 20 * i)#第一个柱子从下到上放
        color = FillColors[i]
        plates[i].color(color)
        plates[i].showturtle()
    return plates
def pole_stack():  # 制造poles的栈
    poles = [Stack() for i in range(3)]
    return poles
def moveDisk(plates, poles, fp, tp):  # 把poles[fp]顶端的盘子plates[mov]，从poles[fp]移到poles[tp]
    mov = poles[fp].peek()
    plates[mov].goto((fp - 1) * 300, 150)
    plates[mov].goto((tp - 1) * 300, 150)
    l = poles[tp].size()  # 确定移动到底部的高度（恰好放在原来最上面的盘子上面）
    plates[mov].goto((tp - 1) * 300, -90 + 20 * l)
def moveTower(plates, poles, height, fromPole, toPole, withPole):  # 递归放盘子，frompole出发的柱子，withpole中间柱子
    if height >= 1:
        moveTower(plates, poles, height - 1, fromPole, withPole, toPole)
        moveDisk(plates, poles, fromPole, toPole)
        poles[toPole].push(poles[fromPole].pop())
        moveTower(plates, poles, height - 1, withPole, toPole, fromPole)
# 编写循环，通过提示框交互数据
J = 1
while J < 100:
    J += 1
    myscreen = turtle.Screen()
    myscreen.title("Hanoi Dynamic Presentation")
    myscreen.setup(800, 600)
    drawpole_3()#画上柱子3个
    try:
        n = int(myscreen.numinput("层数定义窗", "请输入汉诺塔的层数", default=3, minval=1, maxval=8))
    except TypeError:
        exit()
    # n=int(input("请输入汉诺塔的层数并回车:\n"))
    plates = creat_plates(n)#创建n盘子
    poles = pole_stack()#3个柱子作为3个栈
    for i in range(n):
        poles[0].push(i)#第一个柱子上入栈n个盘子
    moveTower(plates, poles, n, 0, 2, 1)
    cstr = int(myscreen.numinput("对话窗", "是否重新进行,1是继续2是退出", default='2', minval=1, maxval=8))
    if cstr == 2:
        myscreen.clear()
        # myscreen.exitonclick() #等待点击后退出
        myscreen.bye()  # 关闭窗口退出
        break
    else:
        myscreen.clear()